package model;

import java.util.ArrayList;

import model.minimax.Evaluator;
import model.minimax.MoveEdge;
import model.minimax.StateNode;
import model.minimax.StatesTree;

/**
 * This class implements the AI player configuration.
 *
 */
public class AIPlayer implements Player
{
    private StatesTree stateTree;
    private String name;

    public AIPlayer()
    {
        this("AI");
    }

    public AIPlayer(String name)
    {
        super();
        this.name = name;
        this.stateTree = new StatesTree();
    }

    @Override
    public String getNextMove(ArrayList<ArrayList<GamePiece>> grid, GamePiece playerPiece) throws Exception
    {
        if (LadderGridHelper.allPositionsAreFree(grid))
        {
            return Slot.getRandomBottomSlot().getBoardPositionString();
        }
        else
        {
            if (this.stateTree.getRoot() == null)
            {
                this.stateTree.setRoot(new StateNode(grid, playerPiece));
            }

            this.stateTree.build(2);

            MoveEdge nextMove = null;
            switch (playerPiece)
            {
                case BLACK:
                    nextMove = this.stateTree.getMinMove();
                    break;
                case WHITE:
                    nextMove = this.stateTree.getMaxMove();
                    break;
                default:
                    throw new Exception("Wrong GamePiece Type (" + playerPiece + ") passed : ");
            }

            if (nextMove != null)
            {
                this.stateTree.setRoot(nextMove.getTargetNode());
                return nextMove.getMove().getBoardPositionString();
            }
            else
            {
                return null;
            }
        }
    }

    @Override
    public String getName()
    {
        return this.name;
    }

    @Override
    public void OnOpponentPlayedMove(String move)
    {
        if (this.stateTree.getRoot() != null)
        {
            MoveEdge opponentPlayedMove = findItem(move, this.stateTree.getRoot().getMoves());
            this.stateTree.setRoot(opponentPlayedMove.getTargetNode());
        }
    }

    // Quick fix, maybe we should change the StateNode#moves attribute type from
    // arraylist
    // to position-keyed hashMap hashMap
    private static MoveEdge findItem(String Position, ArrayList<MoveEdge> moves)
    {
        for (MoveEdge move : moves)
        {
            if (move.getMove().getBoardPositionString().equalsIgnoreCase(Position))
            {
                return move;
            }
        }
        return null;
    }
}
